﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;
using System.Globalization;
using System.IO.IsolatedStorage;
using System.Xml.Serialization;
using System.Diagnostics;

using VirtualDigibox.Entities;
using VirtualDigibox.BusinessService;
using VirtualDigibox.Controls.Settings;

namespace VirtualDigibox
{
    public partial class FormMain : Form
    {
        IsolatedStorageFile isf = null;
        List<Channel> channels = new List<Channel>();
        List<Channel> RecordItems = new List<Channel>();
        XmlSerializer serializer = new XmlSerializer(typeof(List<Channel>));
        IsolatedStorageFileStream isfs = null;
        bool IsLoadingChannels = false;
        List<ProcessScheduler.ProcessScheduleItem> ProcessItems = new List<ProcessScheduler.ProcessScheduleItem>();

        ServiceFacade Service = new ServiceFacade();

        public FormMain()
        {
            InitializeComponent();
            channels = Service.GetChannels();

            if (channels == null)
                channels = new List<Channel>();
            //for schedule start/stop quick testing.
#if DEBUG
            //if (channels.Count > 0)
            //{
            //    channels[0].ScheduleItems.Insert(0, new ScheduleItem { Record = false, Time = DateTime.Now.AddMinutes(1), BroadcastName = "TEST1" });
            //    channels[0].ScheduleItems.Insert(1, new ScheduleItem { Record = false, Time = DateTime.Now.AddMinutes(3), BroadcastName = "TEST2" });

            //}
#endif
            channelBindingSource.DataSource = channels;
            channelBindingSource.ResetBindings(false);
            //LoadRecords();
            
        }

        private void btnLoadChannels_Click(object sender, EventArgs e)
        {
            channels = Service.RefreshChannels();

            IsLoadingChannels = true;
            //cbChannels.Invalidate();
            channelBindingSource.DataSource = channels;
            channelBindingSource.ResetBindings(false);
            

            IsLoadingChannels = false;
            //cbChannels.SelectedIndex = 1;
            //BindSchedule();
        }
       
        private void cbChannels_SelectedIndexChanged(object sender, EventArgs e)
        {
            BindSchedule();
        }
        private void BindSchedule()
        {
            if (!IsLoadingChannels)
            {
                Channel channelSelected = cbChannels.SelectedItem as Channel;
                if (channelSelected == null)
                {
                    List<Channel> cbSource = cbChannels.DataSource as List<Channel>;
                    if (cbSource != null)
                    {
                        channelSelected = cbSource[0];
                    }
                }
                if (channelSelected != null)
                {
                    btnPlay.Enabled = !string.IsNullOrEmpty(channelSelected.DigiTVURL);
                    if (channelSelected.ScheduleItems.Count == 0)
                        channelSelected.ScheduleItems = Service.LoadScheduleByRange(channelSelected, DateTime.Now, DateTime.Now.AddDays(14));
                    List<ScheduleItem> olderItems = channelSelected.ScheduleItems.Where(f => f.Time < DateTime.Now).ToList();

                    ScheduleItem selected = olderItems.Count > 0 ? olderItems.OrderByDescending(o => o.Time).First() : channelSelected.ScheduleItems.FirstOrDefault();
                    DateTime selectedTime = selected != null ? selected.Time : DateTime.Now;
                    scheduleItemBindingSource.DataSource = channelSelected.ScheduleItems.Where(f => f.Time >= selectedTime).ToList();
                }
               
            }
        }
        private void dgSchedule_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right || (e.Button == MouseButtons.Left && e.ColumnIndex == 0))
            {
                ScheduleItem sc = scheduleItemBindingSource[e.RowIndex] as ScheduleItem;
                
                if (sc != null)
                {
                    if (sc.Record && sc.ProcessScheduleItemId.HasValue)
                    {
                        ProcessScheduler.ProcessScheduleItem item = ProcessItems.Where(f => f.Id == sc.ProcessScheduleItemId.Value).FirstOrDefault();
                        if (item != null)
                        {
                            if (!item.CanStop)
                            {
                                DialogResult result = MessageBox.Show(Messages.ProcessIsRunning, "", MessageBoxButtons.YesNoCancel);
                                if (result == DialogResult.Yes)
                                {
                                    item.ForceToStop();
                                }
                                else
                                {
                                    return;
                                }
                            }
                            ProcessItems.Remove(item);
                            sc.ProcessScheduleItemId = null;
                        }
                    }

                    sc.Record = !sc.Record;
                    scheduleItemBindingSource.ResetItem(e.RowIndex);

                    SetScheduledItem(sc, channelBindingSource.Current as Channel);
                }
            }            
        }

       
        private void btnFetchSchedule_Click(object sender, EventArgs e)
        {
            Channel channelSelected = cbChannels.SelectedItem as Channel;
            //LoadKava(channelSelected);
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            // remove test entries if added
#if DEBUG
            //if (channels.Count > 0 && channels[0].ScheduleItems.Count > 0 && channels[0].ScheduleItems[0].BroadcastName.StartsWith("TEST"))
            //{
            //    channels[0].ScheduleItems.RemoveAt(0);
            //    channels[0].ScheduleItems.RemoveAt(1);
            //}
#endif

            
            bool stopAll = false;
            if (ProcessItems.Where(f => f.CanStop == false).Count() > 0)
            {
                DialogResult result = MessageBox.Show(Messages.ProcessIsRunning, "", MessageBoxButtons.YesNoCancel);
                stopAll = result == DialogResult.Yes;
            }

            e.Cancel = !stopAll;

            foreach (ProcessScheduler.ProcessScheduleItem item in ProcessItems)
            {
                item.ForceToStop();
            }
            
            if (!e.Cancel)
                Service.SaveChannels(channels, true);
            else
                Service.SaveChannels(channels, false);

        }

        private void btnPlay_Click(object sender, EventArgs e)
        {
            Channel selectedChannel = (Channel)cbChannels.SelectedItem;
            Process p = new Process();
            p.StartInfo = new ProcessStartInfo(SettingsManager.VLCEXE, selectedChannel.DigiTVURL);
            p.Start();

        }

        private void btnLoadURL_Click(object sender, EventArgs e)
        {
            DialogResult result = openFileDialog1.ShowDialog();
            if (result == DialogResult.OK)
            {
                string[] lines = File.ReadAllLines(openFileDialog1.FileName);

                bool serarchForChannelName = true;
                Channel currentChannel = null;
                foreach (string line in lines)
                {
                    if (serarchForChannelName && line.StartsWith("#EXTINF:0,"))
                    {
                        string chName = line.Replace("#EXTINF:0,", "").Trim();
                        currentChannel = channels.FirstOrDefault(f => f.Name == chName);
                        if (currentChannel != null)
                            serarchForChannelName = false;
                    }
                    else if (!serarchForChannelName && line.StartsWith("udp://"))
                    {
                        currentChannel.DigiTVURL = line.Trim();
                        serarchForChannelName = true;
                    }
                }
            }
            Service.SaveChannels(channels, false);
        }

        private void scheduleItemBindingSource_DataSourceChanged(object sender, EventArgs e)
        {
            //List<ScheduleItem> items = scheduleItemBindingSource.DataSource as List<ScheduleItem>;
            
            //List<ScheduleItem> olderItems = items.Where(f => f.Time < DateTime.Now).ToList();
            //ScheduleItem selected = olderItems.Count > 0 ? olderItems.OrderByDescending(o => o.Time).First() : items.FirstOrDefault();
            //DateTime selectedTime = selected != null ? selected.Time : DateTime.Now;

            //ScheduleItem selected = items.Where(f => f.Time < selectedTime).OrderByDescending(o => o.Time).First();
            //scheduleItemBindingSource.DataSource = channelSelected.ScheduleItems.Where(f => f.Time >= selected.Time).ToList();

            //scheduleItemBindingSource.Position = items.IndexOf(selected);
        }
        private void SetScheduledItem(ScheduleItem sc, Channel c)
        {
            //Channel c = cbChannels.SelectedItem as Channel;
            if (c != null)
            {
                //ScheduleItem sc = (ScheduleItem)scheduleItemBindingSource.Current;
                if (sc != null && sc.Record)
                {
                    ScheduleItem endItem = c.ScheduleItems.Where(f => f.Time > sc.Time).OrderBy(o => o.Time).FirstOrDefault();
                    if (endItem != null)
                    {
                        string arguments = TemplateManager.GetVLCArguments(sc, c);
                        //MessageBox.Show(c.DigiTVURL + string.Format(" :demux=dump :demuxdump-file=\"C:\\TS\\{0}.ts\"", sc.BroadcastName));
                        ProcessScheduler.ProcessScheduleItem item = new ProcessScheduler.ProcessScheduleItem(
                        SettingsManager.VLCEXE , " " + arguments, sc.Time, endItem.Time);
                        sc.ProcessScheduleItemId = item.Id;
                        ProcessItems.Add(item);
                    }
                }
            }
        }
        private void scheduleItemBindingSource_ListChanged(object sender, ListChangedEventArgs e)
        {
            
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void dgSchedule_CellToolTipTextNeeded(object sender, DataGridViewCellToolTipTextNeededEventArgs e)
        {
            Channel ch = channelBindingSource.Current as Channel;

            if (ch != null) 
            {
                ScheduleItem sc = ch.ScheduleItems.ElementAtOrDefault(e.RowIndex);
                if (sc != null)
                {
                    e.ToolTipText = sc.Description;
                }
            }
        }

        private void menuItemSettings_Click(object sender, EventArgs e)
        {
            FormSettings settings = new FormSettings();
            settings.ShowDialog();

        }

       

        
        
    }
}
